package com.promise.jokerdream.repository

import com.promise.jokerdream.database.UserDataManager
import com.promise.jokerdream.network.HttpHelper
import com.promise.jokerdream.network.IHttpCallback
import com.promise.jokerdream.network.PhoneRetryableHttpCallback
import com.promise.jokerdream.response.parser.XiaLvXmlParser
import com.promise.jokerdream.response.parser.FactionFriendXmlParser
import com.promise.jokerdream.response.parser.FriendListXmlParser
import com.promise.jokerdream.response.parser.SimpleXmlParser
import com.promise.jokerdream.response.parser.FightArenaXmlParser
import com.promise.jokerdream.response.parser.FightFactionMineXmlParser
import com.promise.jokerdream.response.parser.FightFriendXmlParser
import com.promise.jokerdream.response.parser.FightTowerXmlParser
import com.promise.jokerdream.response.parser.FightKnightDreamXmlParser
import com.promise.jokerdream.response.parser.FightKnightArenaXmlParser
import com.promise.jokerdream.response.parser.CurrencyExchangeXmlParser
import com.promise.jokerdream.response.parser.PenguinShareXmlParser
import com.promise.jokerdream.response.parser.WulinXmlParser
import com.promise.jokerdream.response.parser.AssistantXmlParser
import com.promise.jokerdream.response.parser.FightProcessXmlParser
import com.promise.jokerdream.response.phone.XiaLvXmlResponse
import com.promise.jokerdream.response.phone.FactionFriendXmlResponse
import com.promise.jokerdream.response.phone.FriendListXmlResponse
import com.promise.jokerdream.response.phone.SimpleXmlResponse
import com.promise.jokerdream.response.phone.FightFactionMineXmlResponse
import com.promise.jokerdream.response.phone.FightTowerXmlResponse
import com.promise.jokerdream.response.phone.FightKnightDreamXmlResponse
import com.promise.jokerdream.response.phone.FightKnightArenaXmlResponse
import com.promise.jokerdream.response.phone.CurrencyExchangeXmlResponse
import com.promise.jokerdream.response.phone.PenguinShareXmlResponse
import com.promise.jokerdream.response.phone.WulinXmlResponse
import com.promise.jokerdream.response.phone.QueryAssistantXmlResponse
import com.promise.jokerdream.response.phone.LatestActXmlResponse
import com.promise.jokerdream.response.phone.FightProcessXmlResponse
import com.promise.jokerdream.response.parser.LatestActXmlParser
import com.promise.jokerdream.utils.AppContext
import kotlinx.coroutines.suspendCancellableCoroutine
import okhttp3.Call
import okhttp3.Response
import java.io.IOException
import kotlin.coroutines.resume

/**
 * 手机端游戏数据仓库
 * 专门处理XML响应的API请求
 */
class PhoneGameRepository {
    
    private val userDataManager by lazy { UserDataManager.getInstance(AppContext.get()) }
    
    companion object {
        @Volatile
        private var INSTANCE: PhoneGameRepository? = null
        
        /**
         * 获取PhoneGameRepository单例
         */
        fun getInstance(): PhoneGameRepository {
            return INSTANCE ?: synchronized(this) {
                INSTANCE ?: PhoneGameRepository().also { INSTANCE = it }
            }
        }
    }
    
    /**
     * 获取当前账号的Cookie并合并到请求头中
     */
    private fun mergeHeaders(headers: Map<String, String>?): Map<String, String> {
        val currentAccount = userDataManager.getCurrentAccount()
        val cookieHeader = currentAccount?.cookie
        
        val mergedHeaders = headers?.toMutableMap() ?: mutableMapOf()
        
        // 添加手机端专用的User-Agent
        mergedHeaders["User-Agent"] = "Mozilla/5.0 (Linux; Android 10; SM-G975F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.120 Mobile Safari/537.36"
        
        if (cookieHeader != null && cookieHeader.isNotEmpty()) {
            mergedHeaders["Cookie"] = cookieHeader
        }
        
        return mergedHeaders
    }
    
    /**
     * 通用的GET请求方法（手机端）
     * @param url 请求URL
     * @param headers 请求头（可选）
     * @param enableRetry 是否启用自动重试，默认为true
     * @param maxRetries 最大重试次数，默认为5次
     * @param retryDelay 重试延迟时间（毫秒），默认为1000ms
     * @return 原始XML响应字符串
     */
    suspend fun get(
        url: String,
        headers: Map<String, String>? = null,
        enableRetry: Boolean = true,
        maxRetries: Int = 5,
        retryDelay: Long = 1000L
    ): Result<String> {
        // 合并用户Cookie到请求头
        val mergedHeaders = mergeHeaders(headers)
        
        return suspendCancellableCoroutine { continuation ->
            val originalCallback = object : IHttpCallback {
                override fun onSuccess(call: Call, response: Response) {
                    try {
                        val responseBody = response.body?.string()
                        if (responseBody != null) {
                            continuation.resume(Result.success(responseBody))
                        } else {
                            continuation.resume(Result.failure(
                                ApiException(
                                    code = -101,
                                    message = "响应体为空"
                                )
                            ))
                        }
                    } catch (e: Exception) {
                        continuation.resume(Result.failure(
                            ApiException(
                                code = -102,
                                message = "获取响应失败: ${e.message}",
                                cause = e
                            )
                        ))
                    }
                }
                
                override fun onFailure(call: Call, error: IOException) {
                    continuation.resume(Result.failure(
                        ApiException(
                            code = -103,
                            message = "网络请求失败: ${error.message}",
                            cause = error
                        )
                    ))
                }
            }
            
            val callback = if (enableRetry) {
                PhoneRetryableHttpCallback(
                    originalCallback = originalCallback,
                    maxRetries = maxRetries,
                    retryDelay = retryDelay,
                    retryRequest = {
                        HttpHelper.get(url, mergedHeaders, originalCallback)
                    }
                )
            } else {
                originalCallback
            }
            
            HttpHelper.get(
                url = url,
                headers = mergedHeaders,
                callback = callback
            )
        }
    }
    
    /**
     * 解析侠侣XML响应
     * @param responseBody XML响应字符串
     * @return 解析后的侠侣数据
     */
    fun parseXiaLvResponse(responseBody: String): Result<XiaLvXmlResponse> {
        return try {
            val parser = XiaLvXmlParser()
            val parseResult = parser.parseXiaLvXml(responseBody)
            if (parseResult.isSuccess && parseResult.data != null) {
                Result.success(parseResult.data)
            } else {
                Result.failure(
                    ApiException(
                        code = -102,
                        message = parseResult.errorMessage ?: "XML解析失败",
                        cause = null
                    )
                )
            }
        } catch (e: Exception) {
            Result.failure(
                ApiException(
                    code = -102,
                    message = "XML解析失败: ${e.message}",
                    cause = e
                )
            )
        }
    }
    
    /**
     * 解析帮友XML响应
     * @param responseBody XML响应字符串
     * @return 解析后的帮友数据
     */
    fun parseFactionFriendResponse(responseBody: String): Result<FactionFriendXmlResponse> {
        return try {
            val parser = FactionFriendXmlParser()
            val parseResult = parser.parseFactionFriendXml(responseBody)
            if (parseResult.isSuccess && parseResult.data != null) {
                Result.success(parseResult.data)
            } else {
                Result.failure(
                    ApiException(
                        code = -102,
                        message = parseResult.errorMessage ?: "XML解析失败",
                        cause = null
                    )
                )
            }
        } catch (e: Exception) {
            Result.failure(
                ApiException(
                    code = -102,
                    message = "XML解析失败: ${e.message}",
                    cause = e
                )
            )
        }
    }
    
    /**
     * 解析好友列表响应
     * @param responseBody 响应体
     * @return 解析后的好友列表数据
     */
    fun parseFriendListResponse(responseBody: String): Result<FriendListXmlResponse> {
        return try {
            val parser = FriendListXmlParser()
            val parseResult = parser.parseFriendListXml(responseBody)
            if (parseResult.isSuccess && parseResult.data != null) {
                Result.success(parseResult.data)
            } else {
                Result.failure(
                    ApiException(
                        code = -102,
                        message = parseResult.errorMessage ?: "XML解析失败",
                        cause = null
                    )
                )
            }
        } catch (e: Exception) {
            Result.failure(
                ApiException(
                    code = -102,
                    message = "XML解析失败: ${e.message}",
                    cause = e
                )
            )
        }
    }
    
    /**
     * 解析竞技场挑战响应
     * @param responseBody 响应体
     * @return 解析后的挑战结果数据
     */
    fun parseArenaChallengeResponse(responseBody: String): Result<SimpleXmlResponse> {
        return try {
            val parser = FightArenaXmlParser()
            val parseResult = parser.extractContent(responseBody)
            if (parseResult.isSuccess && parseResult.data != null) {
                Result.success(SimpleXmlResponse(parseResult.data))
            } else {
                Result.failure(
                    ApiException(
                        code = -102,
                        message = parseResult.errorMessage ?: "竞技场挑战解析失败",
                        cause = null
                    )
                )
            }
        } catch (e: Exception) {
            Result.failure(
                ApiException(
                    code = -102,
                    message = "竞技场挑战解析失败: ${e.message}",
                    cause = e
                )
            )
        }
    }
    
    /**
     * 根据URL自动选择XML解析器
     * @param url 请求URL
     * @param responseBody XML响应字符串
     * @return 解析后的数据
     */
    fun parseXmlResponse(url: String, responseBody: String): Result<Any> {
        return try {
            val simpleXmlParser = SimpleXmlParser()
            val parseResult = simpleXmlParser.parseContent(responseBody)
            if (parseResult.isSuccess && parseResult.data != null) {
                Result.success(SimpleXmlResponse(parseResult.data))
            } else {
                Result.failure(
                    ApiException(
                        code = -102,
                        message = parseResult.errorMessage ?: "XML解析失败",
                        cause = null
                    )
                )
            }
        } catch (e: Exception) {
            Result.failure(
                ApiException(
                    code = -102,
                    message = "XML解析失败: ${e.message}",
                    cause = e
                )
            )
        }
    }
    
    /**
     * 解析矿洞挑战响应
     * @param responseBody 响应体
     * @return 解析后的矿洞挑战数据
     */
    fun parseFightFactionMineResponse(responseBody: String): Result<FightFactionMineXmlResponse> {
        return try {
            val parser = FightFactionMineXmlParser()
            val parseResult = parser.parseFightFactionMineXml(responseBody)
            if (parseResult.isSuccess && parseResult.data != null) {
                Result.success(parseResult.data)
            } else {
                Result.failure(
                    ApiException(
                        code = -102,
                        message = parseResult.errorMessage ?: "XML解析失败",
                        cause = null
                    )
                )
            }
        } catch (e: Exception) {
            Result.failure(
                ApiException(
                    code = -102,
                    message = "XML解析失败: ${e.message}",
                    cause = e
                )
            )
        }
    }
    
    /**
     * 解析武林大会响应
     * @param responseBody 响应体
     * @return 解析后的武林大会数据
     */
    fun parseWulinResponse(responseBody: String): Result<WulinXmlResponse> {
        return try {
            val parser = WulinXmlParser()
            val parseResult = parser.parseWulinXml(responseBody)
            if (parseResult.isSuccess && parseResult.data != null) {
                Result.success(parseResult.data)
            } else {
                Result.failure(
                    ApiException(
                        code = -102,
                        message = parseResult.errorMessage ?: "XML解析失败",
                        cause = null
                    )
                )
            }
        } catch (e: Exception) {
            Result.failure(
                ApiException(
                    code = -102,
                    message = "XML解析失败: ${e.message}",
                    cause = e
                )
            )
        }
    }
    
    /**
     * 解析好友挑战响应
     * @param responseBody 响应体
     * @return 解析后的挑战结果数据
     */
    fun parseFightFriendResponse(responseBody: String): Result<SimpleXmlResponse> {
        return try {
            val parser = FightFriendXmlParser()
            val parseResult = parser.parseFightFriendXml(responseBody)
            if (parseResult.isSuccess && parseResult.data != null) {
                Result.success(SimpleXmlResponse(parseResult.data))
            } else {
                Result.failure(
                    ApiException(
                        code = -102,
                        message = parseResult.errorMessage ?: "好友挑战解析失败",
                        cause = null
                    )
                )
            }
        } catch (e: Exception) {
            Result.failure(
                ApiException(
                    code = -102,
                    message = "好友挑战解析失败: ${e.message}",
                    cause = e
                )
            )
        }
    }
    
    /**
     * 解析斗神塔响应
     * @param responseBody 响应体
     * @return 解析后的斗神塔数据
     */
    fun parseFightTowerResponse(responseBody: String): Result<FightTowerXmlResponse> {
        return try {
            val parser = FightTowerXmlParser()
            val parseResult = parser.parseFightTowerXml(responseBody)
            if (parseResult.isSuccess && parseResult.data != null) {
                Result.success(parseResult.data)
            } else {
                Result.failure(
                    ApiException(
                        code = -102,
                        message = parseResult.errorMessage ?: "斗神塔解析失败",
                        cause = null
                    )
                )
            }
        } catch (e: Exception) {
            Result.failure(
                ApiException(
                    code = -102,
                    message = "斗神塔解析失败: ${e.message}",
                    cause = e
                )
            )
        }
    }
    
    /**
     * 解析江湖长梦XML响应
     * @param responseBody 响应体
     * @return 解析后的江湖长梦数据
     */
    fun parseFightKnightDreamResponse(responseBody: String): Result<FightKnightDreamXmlResponse> {
        return try {
            val parser = FightKnightDreamXmlParser()
            val parseResult = parser.parseFightKnightDreamXml(responseBody)
            if (parseResult.isSuccess && parseResult.data != null) {
                Result.success(parseResult.data)
            } else {
                Result.failure(
                    ApiException(
                        code = -102,
                        message = parseResult.errorMessage ?: "江湖长梦解析失败",
                        cause = null
                    )
                )
            }
        } catch (e: Exception) {
            Result.failure(
                ApiException(
                    code = -102,
                    message = "江湖长梦解析失败: ${e.message}",
                    cause = e
                )
            )
        }
    }
    
    /**
     * 解析乐斗助手XML响应
     * @param responseBody XML响应字符串
     * @return 解析后的助手数据
     */
    fun parseAssistantResponse(responseBody: String): Result<QueryAssistantXmlResponse> {
        return try {
            val parser = AssistantXmlParser()
            val parseResult = parser.parseXml(responseBody)
            if (parseResult.isSuccess && parseResult.data != null) {
                Result.success(parseResult.data)
            } else {
                Result.failure(
                    ApiException(
                        code = -102,
                        message = parseResult.errorMessage ?: "乐斗助手解析失败",
                        cause = null
                    )
                )
            }
        } catch (e: Exception) {
            Result.failure(
                ApiException(
                    code = -102,
                    message = "乐斗助手解析失败: ${e.message}",
                    cause = e
                )
            )
        }
    }
    
    /**
     * 解析侠士论剑挑战响应
     * @param responseBody 响应体
     * @return 解析后的侠士论剑挑战数据
     */
    fun parseFightKnightArenaResponse(responseBody: String): Result<FightKnightArenaXmlResponse> {
        return try {
            val parser = FightKnightArenaXmlParser()
            val parseResult = parser.parseFightKnightArenaXml(responseBody)
            if (parseResult.isSuccess && parseResult.data != null) {
                Result.success(parseResult.data)
            } else {
                Result.failure(
                    ApiException(
                        code = -102,
                        message = parseResult.errorMessage ?: "侠士论剑挑战解析失败",
                        cause = null
                    )
                )
            }
        } catch (e: Exception) {
            Result.failure(
                ApiException(
                    code = -102,
                    message = "侠士论剑挑战解析失败: ${e.message}",
                    cause = e
                )
            )
        }
    }
    
    /**
     * 解析货币兑换响应
     * @param responseBody 响应体
     * @return 解析后的货币兑换数据
     */
    fun parseCurrencyExchangeResponse(responseBody: String): Result<CurrencyExchangeXmlResponse> {
        return try {
            val parser = CurrencyExchangeXmlParser()
            val parseResult = parser.parseCurrencyExchangeXml(responseBody)
            if (parseResult.isSuccess && parseResult.data != null) {
                Result.success(parseResult.data)
            } else {
                Result.failure(
                    ApiException(
                        code = -102,
                        message = parseResult.errorMessage ?: "货币兑换解析失败",
                        cause = null
                    )
                )
            }
        } catch (e: Exception) {
            Result.failure(
                ApiException(
                    code = -102,
                    message = "货币兑换解析失败: ${e.message}",
                    cause = e
                )
            )
        }
    }
    
    /**
     * 解析企鹅分享响应
     * @param responseBody 响应体
     * @return 解析后的企鹅分享数据
     */
    fun parsePenguinShareResponse(responseBody: String): Result<PenguinShareXmlResponse> {
        return try {
            val parser = PenguinShareXmlParser()
            val parseResult = parser.parsePenguinShareXml(responseBody)
            if (parseResult.isSuccess && parseResult.data != null) {
                Result.success(parseResult.data)
            } else {
                Result.failure(
                    ApiException(
                        code = -102,
                        message = parseResult.errorMessage ?: "企鹅分享解析失败",
                        cause = null
                    )
                )
            }
        } catch (e: Exception) {
            Result.failure(
                ApiException(
                    code = -102,
                    message = "企鹅分享解析失败: ${e.message}",
                    cause = e
                )
            )
        }
    }
    
    /**
     * 解析最新活动XML响应
     * @param responseBody 响应体
     * @return 解析后的最新活动数据
     */
    fun parseLatestActResponse(responseBody: String): Result<LatestActXmlResponse> {
        return try {
            val parser = LatestActXmlParser()
            val parseResult = parser.parseLatestActXml(responseBody)
            if (parseResult.isSuccess && parseResult.data != null) {
                Result.success(parseResult.data)
            } else {
                Result.failure(
                    ApiException(
                        code = -102,
                        message = parseResult.errorMessage ?: "最新活动解析失败",
                        cause = null
                    )
                )
            }
        } catch (e: Exception) {
            Result.failure(
                ApiException(
                    code = -102,
                    message = "最新活动解析失败: ${e.message}",
                    cause = e
                )
            )
        }
    }
    
    /**
     * 解析战斗过程响应
     * @param responseBody 响应体
     * @return 解析后的战斗过程数据
     */
    fun parseFightProcessResponse(responseBody: String): Result<FightProcessXmlResponse> {
        return try {
            val parser = FightProcessXmlParser()
            val parseResult = parser.parseFightProcessXml(responseBody)
            if (parseResult.isSuccess && parseResult.data != null) {
                Result.success(parseResult.data)
            } else {
                Result.failure(
                    ApiException(
                        code = -102,
                        message = parseResult.errorMessage ?: "战斗过程解析失败",
                        cause = null
                    )
                )
            }
        } catch (e: Exception) {
            Result.failure(
                ApiException(
                    code = -102,
                    message = "战斗过程解析失败: ${e.message}",
                    cause = e
                )
            )
        }
    }
}
